﻿using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Baula.TextGen.Framework.Tests
{
    [TestClass]
    public class PartTests
    {
        [TestMethod]
        public void RenderToString_WithLiteralTemplatePartAddedOnce_ReturnsTheTemplateWithoutPartHeading()
        {
            const string templateContent =
                @"This is the main part
' === This is the part
This is the content of the part.";
            const string expectedContent =
                @"This is the main part
This is the content of the part.";

            var documentTemplate = new DocumentTemplate(templateContent);
            var document = documentTemplate.CreateDocument();
            var part = documentTemplate.PartTemplates["This is the part"].CreatePart();

            document.Parts.Add(part);
            var actualContent = document.RenderToString();

            Assert.AreEqual(expectedContent, actualContent);
        }

        [TestMethod]
        public void RenderToString_WithLiteralTemplatePartAddedFourTimes_ReturnsTheMainPartWithFourAdditionalPartsAdded()
        {
            const string templateContent =
                @"This is the main part
' === This is the part
This is the content of the part.";
            const string expectedText = @"This is the main part
This is the content of the part.
This is the content of the part.
This is the content of the part.
This is the content of the part.";

            var documentTemplate = new DocumentTemplate(templateContent);
            var document = documentTemplate.CreateDocument();
            var part = documentTemplate.PartTemplates["This is the part"].CreatePart();

            document.Parts.Add(part);
            document.Parts.Add(part);
            document.Parts.Add(part);
            document.Parts.Add(part);
            var actualContent = document.RenderToString();

            Assert.AreEqual(expectedText, actualContent);
        }

        [TestMethod]
        public void RenderToString_WithSinglePlaceholderPartTemplateAddedOnce_ReturnsTheMainPartWithOneAdditionalPartAndReplacedPlaceholder()
        {
            const string templateContent =
                @"This is the main part
' === This is the part
This is the content with a %CoolPlaceholder%.";
            const string expectedText =
                @"This is the main part
This is the content with a Pfau.";

            var documentTemplate = new DocumentTemplate(templateContent);
            var document = documentTemplate.CreateDocument();
            var part = documentTemplate.PartTemplates["This is the part"].CreatePart();
            part.ValuesForPlaceholders["CoolPlaceholder"] = "Pfau";
            document.Parts.Add(part);
            var actualText = document.RenderToString();

            Assert.AreEqual(expectedText, actualText);
        }

        [TestMethod]
        public void RenderToString_WithSinglePlaceholderPartTemplateAddedTwice_ReturnsTheMainPartWithTwoAdditionalPartsAndReplacedPlaceholders()
        {
            const string templateContent =
                @"This is the main part
' === This is the part
This is the content with a %CoolPlaceholder%.";
            const string expectedText =
                @"This is the main part
This is the content with a Pfau.
This is the content with a Boa.";

            var documentTemplate = new DocumentTemplate(templateContent);
            var document = documentTemplate.CreateDocument();
            // 1st part
            var part = documentTemplate.PartTemplates["This is the part"].CreatePart();
            part.ValuesForPlaceholders["CoolPlaceholder"] = "Pfau";
            document.Parts.Add(part);
            // 2nd part
            part = documentTemplate.PartTemplates["This is the part"].CreatePart();
            part.ValuesForPlaceholders["CoolPlaceholder"] = "Boa";
            document.Parts.Add(part);

            var actualText = document.RenderToString();

            Assert.AreEqual(expectedText, actualText);
        }

        [TestMethod]
        public void RenderToString_WithRenderModeHeading_RendersPlaceholderSectionHeadingBeforeTheContent()
        {
            const string templateContent = @"Main Part
' %Section:MySection%
' === MyPartTemplate
' @Section:MySection
Part%PartNumber%";
            const string expectedText = @"Main Part
' %Section:MySection%
Part1
Part2
Part3";
            var actualText = RenderDocumentByAddingThreePartsWithNumber(templateContent, RenderMode.Heading);

            Assert.AreEqual(expectedText, actualText);
        }

        [TestMethod]
        public void RenderToString_WithRenderModeUpdatable_RendersPlaceholderSectionHeadingAfterTheContent()
        {
            const string templateContent = @"Main Part
' %Section:MySection%
' === MyPartTemplate
' @Section:MySection
Part%PartNumber%";
            const string expectedText = @"Main Part
Part1
Part2
Part3
' %Section:MySection%";
            var actualText = RenderDocumentByAddingThreePartsWithNumber(templateContent, RenderMode.Updatable);

            Assert.AreEqual(expectedText, actualText);
        }

        [TestMethod]
        public void RenderToString_WithRenderModeFinal_RendersNoPlaceholderSectionHeading()
        {
            const string templateContent = @"Main Part
' %Section:MySection%
' === MyPartTemplate
' @Section:MySection
Part%PartNumber%";
            const string expectedText = @"Main Part
Part1
Part2
Part3";
            var actualText = RenderDocumentByAddingThreePartsWithNumber(templateContent, RenderMode.Final);

            Assert.AreEqual(expectedText, actualText);
        }

        private string RenderDocumentByAddingThreePartsWithNumber(string templateContent, RenderMode renderMode)
        {
            var documentTemplate = new DocumentTemplate(templateContent);
            var document = documentTemplate.CreateDocument();

            for (var i = 0; i < 3; i++)
            {
                var part = documentTemplate.PartTemplates["MyPartTemplate"].CreatePart();
                part.ValuesForPlaceholders["PartNumber"] = (i+1).ToString();
                document.Parts.Add(part);
            }

            return document.RenderToString(renderMode);
        }
    }
}
